Pythonã®ã€ãã¬ãŒã·ã§ã³ã®åãè§£æŸã__iter__ãš__next__ã¡ãœããã䜿ã£ãã«ã¹ã¿ã ã€ãã¬ãŒã¿ã®å®è£ ã«ã€ããŠãå®è·µçãªå®äŸã亀ããŠè§£èª¬ããã°ããŒãã«éçºè åãç·åã¬ã€ãã
Pythonã®ã€ãã¬ãŒã¿ãããã³ã«ãè§£ãæãã: __iter__ãš__next__ã®è©³çްãªè§£èª¬
ã€ãã¬ãŒã·ã§ã³ã¯ããã°ã©ãã³ã°ã«ãããŠæãåºæ¬çãªæŠå¿µã®äžã€ã§ããPythonã§ã¯ãåçŽãªforã«ãŒãããè€éãªããŒã¿åŠçãã€ãã©ã€ã³ãŸã§ããããããã®ãåããæŽç·Žãããå¹ççãªã¡ã«ããºã ã§ãããªã¹ããã«ãŒããããããã¡ã€ã«ããè¡ãèªã¿èŸŒãã ããããŒã¿ããŒã¹ã®çµæãæ±ã£ããããéã«æ¯æ¥äœ¿ã£ãŠããŸãããããããã®å éšã§äœãèµ·ãã£ãŠããã®ãèããããšã¯ãããŸããïŒPythonã¯ã©ã®ããã«ããŠãããã»ã©å€ãã®ç°ãªãçš®é¡ã®ãªããžã§ã¯ããããæ¬¡ã®ãã¢ã€ãã ãååŸããæ¹æ³ãç¥ãã®ã§ããããïŒ
ãã®çãã¯ãã€ãã¬ãŒã¿ãããã³ã«ãšããŠç¥ããã匷åã§æŽç·Žããããã¶ã€ã³ãã¿ãŒã³ã«ãããŸãããã®ãããã³ã«ã¯ãPythonã®ãã¹ãŠã®ã·ãŒã±ã³ã¹ã©ã€ã¯ãªãªããžã§ã¯ãã話ãå ±éèšèªã§ãããã®ãããã³ã«ãçè§£ãå®è£ ããããšã§ãPythonã®ã€ãã¬ãŒã·ã§ã³ããŒã«ãšå®å šã«äºææ§ã®ããç¬èªã®ã«ã¹ã¿ã ãªããžã§ã¯ããäœæã§ããã³ãŒãããã衚çŸè±ãã§ã¡ã¢ãªå¹çãé«ãããããŠå žåçãªãPythonãããããã®ã«ããããšãã§ããŸãã
ãã®ç·åã¬ã€ãã§ã¯ãã€ãã¬ãŒã¿ãããã³ã«ãæ·±ãæãäžããŠãããŸãã`__iter__`ã¡ãœãããš`__next__`ã¡ãœããã®èåŸã«ããéæ³ãè§£ãæãããã€ãã©ãã«ãšã€ãã¬ãŒã¿ã®æ±ºå®çãªéããæç¢ºã«ããç¬èªã®ã«ã¹ã¿ã ã€ãã¬ãŒã¿ããŒãããæ§ç¯ããæ¹æ³ã段éçã«èª¬æããŸããPythonã®å éšæ§é ãžã®çè§£ãæ·±ãããäžçŽéçºè ã§ãã£ãŠããããæŽç·ŽãããAPIã®èšèšãç®æããšãã¹ããŒãã§ãã£ãŠããã€ãã¬ãŒã¿ãããã³ã«ãç¿åŸããããšã¯ãããªãã®æ è·¯ã«ãããéèŠãªäžæ©ãšãªãã§ãããã
ããªãã: ã€ãã¬ãŒã·ã§ã³ã®éèŠæ§ãšå
æè¡çãªå®è£ ã«æ·±ãå ¥ãåã«ãã€ãã¬ãŒã¿ãããã³ã«ããªãããã»ã©éèŠãªã®ããçè§£ããããšãäžå¯æ¬ ã§ãããã®å©ç¹ã¯ãåã«`for`ã«ãŒããå¯èœã«ããã ãã«ãšã©ãŸããŸããã
ã¡ã¢ãªå¹çãšé å»¶è©äŸ¡
æ°ã®ã¬ãã€ãã«ãåã¶å·šå€§ãªãã°ãã¡ã€ã«ãåŠçããå¿ èŠããããšæ³åããŠãã ããããããã¡ã€ã«å šäœãã¡ã¢ãªã«ãªã¹ããšããŠèªã¿èŸŒãã å Žåãã·ã¹ãã ã®ãªãœãŒã¹ã䜿ãæãããŠããŸãå¯èœæ§ãé«ãã§ããããã€ãã¬ãŒã¿ã¯ãé å»¶è©äŸ¡ãšåŒã°ããæŠå¿µãéããŠããã®åé¡ã elegantly ã«è§£æ±ºããŸãã
ã€ãã¬ãŒã¿ã¯ãã¹ãŠã®ããŒã¿ãäžåºŠã«èªã¿èŸŒãããã§ã¯ãããŸããã代ããã«ãèŠæ±ãããå Žåã«ã®ã¿ãäžåºŠã«1ã€ã®ã¢ã€ãã ãçæãŸãã¯ãã§ããããŸããã·ãŒã±ã³ã¹å ã®ã©ãã«ããããèšæ¶ããããã®å éšç¶æ ãç¶æããŸããããã¯ãçè«äžãéåžžã«å°éã§äžå®ã®ã¡ã¢ãªéã§ç¡éã«å€§ããªããŒã¿ã¹ããªãŒã ãåŠçã§ããããšãæå³ããŸããããã¯ãããã°ã©ã ãã¯ã©ãã·ã¥ãããããšãªãã巚倧ãªãã¡ã€ã«ã1è¡ãã€èªã¿èŸŒãããšãå¯èœã«ããã®ãšåãååã§ãã
ã¯ãªãŒã³ã§èªã¿ããããæ®éçãªã³ãŒã
ã€ãã¬ãŒã¿ãããã³ã«ã¯ãé æ¬¡ã¢ã¯ã»ã¹ããããã®æ®éçãªã€ã³ã¿ãŒãã§ãŒã¹ãæäŸããŸãããªã¹ããã¿ãã«ãèŸæžãæååããã¡ã€ã«ãªããžã§ã¯ãããã®ä»å€ãã®åããã¹ãŠãã®ãããã³ã«ã«æºæ ããŠããããããã¹ãŠã«å¯ŸããŠåãæ§æã§ãã`for`ã«ãŒãã䜿çšããŠäœæ¥ã§ããŸãããã®çµ±äžæ§ã¯ãPythonã®å¯èªæ§ã®èŠç³ã§ãã
ãã®ã³ãŒããèããŠã¿ãŸããã:
ã³ãŒã:
my_list = [1, 2, 3]
for item in my_list:
print(item)
my_string = "abc"
for char in my_string:
print(char)
with open('my_file.txt', 'r') as f:
for line in f:
print(line)
`for`ã«ãŒãã¯ããããæŽæ°ã®ãªã¹ããã€ãã¬ãŒãããŠããã®ããæååã®æåãã€ãã¬ãŒãããŠããã®ãããã¡ã€ã«ããã®è¡ãã€ãã¬ãŒãããŠããã®ããæ°ã«ããŸãããåã«ãªããžã§ã¯ãã«ã€ãã¬ãŒã¿ãèŠæ±ããæ¬¡ã«ã€ãã¬ãŒã¿ã«æ¬¡ã®ã¢ã€ãã ãç¹°ãè¿ãèŠæ±ããã ãã§ãããã®æœè±¡åã¯ä¿¡ããããªãã»ã©åŒ·åã§ãã
ã€ãã¬ãŒã¿ãããã³ã«ã®è§£äœ
ãããã³ã«èªäœã¯é©ãã»ã©ã·ã³ãã«ã§ãããã³ãâã(äºéã¢ã³ããŒã¹ã³ã¢)ã¡ãœãããšããåŒã°ãã2ã€ã®ç¹æ®ã¡ãœããã«ãã£ãŠå®çŸ©ãããŠããŸã:
- `__iter__`()
- `__next__`()
ããããå®å šã«çè§£ããããã«ã¯ããŸããé¢é£ããŠãããç°ãªã2ã€ã®æŠå¿µãããªãã¡ã€ãã©ãã«ãšã€ãã¬ãŒã¿ã®åºå¥ãçè§£ããå¿ èŠããããŸãã
ã€ãã©ãã« vs. ã€ãã¬ãŒã¿: 決å®çãªéã
ããã¯åå¿è ã«ãšã£ãŠãã°ãã°æ··ä¹±ã®å ãšãªããŸããããã®éãã¯éåžžã«éèŠã§ãã
ã€ãã©ãã«ãšã¯ïŒ
ã€ãã©ãã«ãšã¯ãã«ãŒãåŠçãå¯èœãªãããããªããžã§ã¯ãã§ããããã¯ãçµã¿èŸŒã¿ã®`iter()`颿°ã«æž¡ããŠã€ãã¬ãŒã¿ãååŸã§ãããªããžã§ã¯ãã§ããæè¡çã«ã¯ããªããžã§ã¯ãã`__iter__`ã¡ãœãããå®è£ ããŠããå Žåãããã¯ã€ãã©ãã«ã§ãããšèŠãªãããŸãããã®`__iter__`ã¡ãœããã®å¯äžã®ç®çã¯ãã€ãã¬ãŒã¿ãªããžã§ã¯ããè¿ãããšã§ãã
çµã¿èŸŒã¿ã€ãã©ãã«ã®äŸã«ã¯ä»¥äžãå«ãŸããŸã:
- ãªã¹ã (`[1, 2, 3]`)
- ã¿ãã« (`(1, 2, 3)`)
- æåå (`"hello"`)
- èŸæž (`{'a': 1, 'b': 2}` - ããŒãã€ãã¬ãŒãããŸã)
- ã»ãã (`{1, 2, 3}`)
- ãã¡ã€ã«ãªããžã§ã¯ã
ã€ãã©ãã«ã¯ãã³ã³ãããŸãã¯ããŒã¿ã®ãœãŒã¹ãšèããããšãã§ããŸããããèªäœã¯ã¢ã€ãã ãçæããæ¹æ³ãç¥ããŸããããçæã§ãããªããžã§ã¯ã (ã€ãã¬ãŒã¿) ãäœæããæ¹æ³ãç¥ã£ãŠããŸãã
ã€ãã¬ãŒã¿ãšã¯ïŒ
ã€ãã¬ãŒã¿ãšã¯ãã€ãã¬ãŒã·ã§ã³äžã«å®éã«å€ãçæããäœæ¥ãè¡ããªããžã§ã¯ãã§ããããŒã¿ã®ã¹ããªãŒã ã衚ããŸããã€ãã¬ãŒã¿ã¯2ã€ã®ã¡ãœãããå®è£ ããå¿ èŠããããŸã:
- `__iter__`(): ãã®ã¡ãœããã¯ã€ãã¬ãŒã¿ãªããžã§ã¯ãèªäœ (`self`) ãè¿ãã¹ãã§ããããã¯ã`for`ã«ãŒããªã©ãã€ãã©ãã«ãæåŸ ãããå Žæã§ã€ãã¬ãŒã¿ã䜿çšã§ããããã«ããããã«å¿ èŠã§ãã
- `__next__`(): ãã®ã¡ãœããã¯ã€ãã¬ãŒã¿ã®ãšã³ãžã³ã§ããã·ãŒã±ã³ã¹å ã®æ¬¡ã®ã¢ã€ãã ãè¿ããŸããè¿ãã¢ã€ãã ããªããªããšãå¿ ã`StopIteration`äŸå€ãçºçãããªããã°ãªããŸããããã®äŸå€ã¯ãšã©ãŒã§ã¯ãªããã€ãã¬ãŒã·ã§ã³ãå®äºããããšãã«ãŒãæ§é ã«ç¥ãããæšæºçãªã·ã°ãã«ã§ãã
ã€ãã¬ãŒã¿ã®äž»ãªç¹åŸŽã¯æ¬¡ã®ãšããã§ã:
- ç¶æ ãä¿æãã: ã€ãã¬ãŒã¿ã¯ã·ãŒã±ã³ã¹å ã®çŸåšã®äœçœ®ãèšæ¶ããŠããŸãã
- å€ãäžåºŠã«1ã€ãã€çæãã: `__next__`ã¡ãœãããä»ããŠã
- 䜿ãåãã§ãã: ã€ãã¬ãŒã¿ãå®å šã«æ¶è²»ããããš (`StopIteration`ãçºçãããåŸ)ãããã¯ç©ºã«ãªããŸãããªã»ãããããåå©çšãããããããšã¯ã§ããŸãããå床ã€ãã¬ãŒã·ã§ã³ãè¡ãã«ã¯ãå ã®ã€ãã©ãã«ã«æ»ããå床`iter()`ãåŒã³åºãããšã§æ°ããã€ãã¬ãŒã¿ãååŸããå¿ èŠããããŸãã
åããŠã®ã«ã¹ã¿ã ã€ãã¬ãŒã¿ã®æ§ç¯: ã¹ããããã€ã¹ãããã¬ã€ã
çè«ãçŽ æŽãããã§ããããããã³ã«ãçè§£ããæåã®æ¹æ³ã¯ãèªåã§æ§ç¯ããããšã§ããéå§çªå·ããå¶éãŸã§ã€ãã¬ãŒã·ã§ã³ãè¡ãã«ãŠã³ã¿ãŒãšããŠæ©èœããã·ã³ãã«ãªã¯ã©ã¹ãäœæããŠã¿ãŸãããã
äŸ1: ã·ã³ãã«ãªã«ãŠã³ã¿ãŒã¯ã©ã¹
`CountUpTo`ãšããã¯ã©ã¹ãäœæããŸãããã®ã€ã³ã¹ã¿ã³ã¹ãäœæããéã«æå€§æ°ãæå®ãããããã€ãã¬ãŒããããšã1ãããã®æå€§æ°ãŸã§ã®æ°å€ãçæããŸãã
ã³ãŒã:
class CountUpTo:
"""An iterator that counts from 1 up to a specified maximum number."""
def __init__(self, max_num):
print("Initializing the CountUpTo object...")
self.max_num = max_num
self.current = 0 # This will store the state
def __iter__(self):
print("__iter__ called, returning self...")
# This object is its own iterator, so we return self
return self
def __next__(self):
print("__next__ called...")
if self.current < self.max_num:
self.current += 1
return self.current
else:
# This is the crucial part: signal that we are done.
print("Raising StopIteration.")
raise StopIteration
# How to use it
print("Creating the counter object...")
counter = CountUpTo(3)
print("\nStarting the for loop...")
for number in counter:
print(f"For loop received: {number}")
ã³ãŒãã®åè§£ãšèª¬æ
`for`ã«ãŒããå®è¡ããããšãã«äœãèµ·ãããåæããŠã¿ãŸããã:
- åæå: `counter = CountUpTo(3)`ãã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ãäœæããŸãã`__init__`ã¡ãœãããå®è¡ããã`self.max_num`ã3ã«ã`self.current`ã0ã«èšå®ãããŸããããã§ãªããžã§ã¯ãã®ç¶æ ãåæåãããŸããã
- ã«ãŒãã®éå§: `for number in counter:`ã®è¡ã«å°éãããšãPythonã¯å éšçã«`iter(counter)`ãåŒã³åºããŸãã
- `__iter__`ãåŒã³åºããã: `iter(counter)`ã®åŒã³åºãã¯ã`counter.__iter__()`ã¡ãœãããèµ·åããŸããã³ãŒããããããããã«ããã®ã¡ãœããã¯åã«ã¡ãã»ãŒãžãåºåãã`self`ãè¿ããŸããããã¯`for`ã«ãŒãã«ã`__next__`ãåŒã³åºãå¿ èŠããããªããžã§ã¯ãã¯ç§èªèº«ã ïŒããšäŒããŸãã
- ã«ãŒãã®éå§: ããã§`for`ã«ãŒãã®æºåãã§ããŸãããåã€ãã¬ãŒã·ã§ã³ã§ãåãåã£ãã€ãã¬ãŒã¿ãªããžã§ã¯ã (ã€ãŸã`counter`ãªããžã§ã¯ã) ã«å¯ŸããŠ`next()`ãåŒã³åºããŸãã
- æåã®`__next__`åŒã³åºã: `counter.__next__()`ã¡ãœãããåŒã³åºãããŸãã`self.current`ã¯0ã§ããã`self.max_num` (3) ããå°ããã§ããã³ãŒãã¯`self.current`ã1ã€ã³ã¯ãªã¡ã³ãããŠãããè¿ããŸãã`for`ã«ãŒãã¯ãã®å€ã`number`倿°ã«ä»£å ¥ããã«ãŒãæ¬äœ (`print(...)`) ãå®è¡ãããŸãã
- 2åç®ã®`__next__`åŒã³åºã: ã«ãŒãã¯ç¶è¡ãããŸãã`__next__`ãå床åŒã³åºãããŸãã`self.current`ã¯1ã§ããããã¯2ã«ã€ã³ã¯ãªã¡ã³ããããŠè¿ãããŸãã
- 3åç®ã®`__next__`åŒã³åºã: `__next__`ãå床åŒã³åºãããŸãã`self.current`ã¯2ã§ããããã¯3ã«ã€ã³ã¯ãªã¡ã³ããããŠè¿ãããŸãã
- æåŸã®`__next__`åŒã³åºã: `__next__`ãããäžåºŠåŒã³åºãããŸããçŸåšã`self.current`ã¯3ã§ããæ¡ä»¶`self.current < self.max_num`ã¯åœã§ãã`else`ãããã¯ãå®è¡ããã`StopIteration`ãçºçããŸãã
- ã«ãŒãã®çµäº: `for`ã«ãŒãã¯`StopIteration`äŸå€ããã£ããããããã«èšèšãããŠããŸããäŸå€ããã£ãããããšãã€ãã¬ãŒã·ã§ã³ãçµäºããããšãèªèããåªé ã«çµäºããŸããããã°ã©ã ã¯ã«ãŒãåŸã®ã³ãŒãã®å®è¡ãç¶è¡ããŸãã
éèŠãªè©³çŽ°ã«æ³šç®ããŠãã ãã: åã`counter`ãªããžã§ã¯ãã«å¯ŸããŠå床`for`ã«ãŒããå®è¡ããããšããŠããæ©èœããŸãããã€ãã¬ãŒã¿ã¯äœ¿ãæããããŠããŸãã`self.current`ã¯ãã§ã«3ãªã®ã§ããã®åŸã®`__next__`ã®åŒã³åºãã¯ããã«`StopIteration`ãçºçãããŸããããã¯ããªããžã§ã¯ããããèªèº«ã®ã€ãã¬ãŒã¿ã§ããããšã®çµæã§ãã
é«åºŠãªã€ãã¬ãŒã¿ã®æŠå¿µãšå®äžçã§ã®å¿çš
ã·ã³ãã«ãªã«ãŠã³ã¿ãŒã¯åŠç¿ã«æé©ã§ãããã€ãã¬ãŒã¿ãããã³ã«ã®çã®åã¯ãããè€éãªã«ã¹ã¿ã ããŒã¿æ§é ã«é©çšããããšãã«èŒããŸãã
ã€ãã©ãã«ãšã€ãã¬ãŒã¿ãçµã¿åãããéã®åé¡
`CountUpTo`ã®äŸã§ã¯ãã¯ã©ã¹ãã€ãã©ãã«ã§ããã€ãã¬ãŒã¿ã§ããããŸãããããã¯ã·ã³ãã«ã§ããã倧ããªæ¬ ç¹ããããŸã: çµæãšããŠåŸãããã€ãã¬ãŒã¿ã¯äœ¿ãåãã§ããäžåºŠã«ãŒãåŠçãè¡ããšãããã§çµããã§ãã
ã³ãŒã:
counter = CountUpTo(2)
print("First iteration:")
for num in counter: print(num) # Works fine
print("\nSecond iteration:")
for num in counter: print(num) # Prints nothing!
ããã¯ãç¶æ (`self.current`) ããªããžã§ã¯ãèªäœã«ä¿åãããŠããããã«èµ·ãããŸããæåã®ã«ãŒãã®åŸã`self.current`ã¯2ã«ãªãããã以éã®`__next__`ã®åŒã³åºãã¯`StopIteration`ãçºçãããã ãã§ãããã®æåã¯ãè€æ°åã€ãã¬ãŒãã§ããæšæºçãªPythonãªã¹ããšã¯ç°ãªããŸãã
ããå ç¢ãªãã¿ãŒã³: ã€ãã©ãã«ãšã€ãã¬ãŒã¿ã®åé¢
Pythonã®çµã¿èŸŒã¿ã³ã¬ã¯ã·ã§ã³ã®ãããªåå©çšå¯èœãªã€ãã©ãã«ãäœæããã«ã¯ã2ã€ã®åœ¹å²ãåé¢ããã®ãæåã®æ¹æ³ã§ããã³ã³ãããªããžã§ã¯ããã€ãã©ãã«ãšãªãããã®`__iter__`ã¡ãœãããåŒã³åºããããã³ã«ãæ°ãããã¬ãã·ã¥ãªã€ãã¬ãŒã¿ãªããžã§ã¯ããçæããŸãã
äŸã2ã€ã®ã¯ã©ã¹ã«ãªãã¡ã¯ã¿ãªã³ã°ããŠã¿ãŸããã: `Sentence` (ã€ãã©ãã«) ãš `SentenceIterator` (ã€ãã¬ãŒã¿)ã
ã³ãŒã:
class SentenceIterator:
"""The iterator responsible for state and producing values."""
def __init__(self, words):
self.words = words
self.index = 0
def __next__(self):
try:
word = self.words[self.index]
except IndexError:
raise StopIteration()
self.index += 1
return word
def __iter__(self):
# An iterator must also be an iterable, returning itself.
return self
class Sentence:
"""The iterable container class."""
def __init__(self, text):
# The container holds the data.
self.words = text.split()
def __iter__(self):
# Each time __iter__ is called, it creates a NEW iterator object.
return SentenceIterator(self.words)
# How to use it
my_sentence = Sentence('This is a test')
print("First iteration:")
for word in my_sentence:
print(word)
print("\nSecond iteration:")
for word in my_sentence:
print(word)
ããã§ããªã¹ããšãŸã£ããåãããã«æ©èœããŸãïŒ`for`ã«ãŒããéå§ããããã³ã«ã`my_sentence.__iter__()`ãåŒã³åºãããããèªèº«ã®ç¶æ (`self.index = 0`) ãæã€æ°ãã`SentenceIterator`ã€ã³ã¹ã¿ã³ã¹ãäœæãããŸããããã«ãããåã`Sentence`ãªããžã§ã¯ãã«å¯ŸããŠè€æ°åãç¬ç«ããã€ãã¬ãŒã·ã§ã³ãå¯èœã«ãªããŸãããã®ãã¿ãŒã³ã¯ã¯ããã«å ç¢ã§ãããPythonèªèº«ã®ã³ã¬ã¯ã·ã§ã³ãå®è£ ãããŠããæ¹æ³ã§ãã
äŸ: ç¡éã€ãã¬ãŒã¿
ã€ãã¬ãŒã¿ã¯æéã§ããå¿ èŠã¯ãããŸãããç¡éã®ããŒã¿ã·ãŒã±ã³ã¹ã衚ãããšãã§ããŸããããããé å»¶çã§äžåºŠã«1ã€ãã€çæãããšããç¹æ§ã倧ããªå©ç¹ãšãªãå Žé¢ã§ãããã£ããããæ°ã®ç¡éã·ãŒã±ã³ã¹ã®ããã®ã€ãã¬ãŒã¿ãäœæããŠã¿ãŸãããã
ã³ãŒã:
class FibonacciIterator:
"""Generates an infinite sequence of Fibonacci numbers."""
def __init__(self):
self.a, self.b = 0, 1
def __iter__(self):
return self
def __next__(self):
result = self.a
self.a, self.b = self.b, self.a + self.b
return result
# How to use it - CAUTION: Infinite loop without a break!
fib_gen = FibonacciIterator()
for i, num in enumerate(fib_gen):
print(f"Fibonacci({i}): {num}")
if i >= 10: # We must provide a stopping condition
break
ãã®ã€ãã¬ãŒã¿ã¯ãããèªäœã§`StopIteration`ãçºçãããããšã¯ãããŸãããã«ãŒããçµäºãããæ¡ä»¶ (`break`æãªã©) ãæäŸããã®ã¯ãåŒã³åºãå ã®ã³ãŒãã®è²¬ä»»ã§ãããã®ãã¿ãŒã³ã¯ãããŒã¿ã¹ããªãŒãã³ã°ãã€ãã³ãã«ãŒããæ°å€ã·ãã¥ã¬ãŒã·ã§ã³ã§äžè¬çã§ãã
Pythonãšã³ã·ã¹ãã ã«ãããã€ãã¬ãŒã¿ãããã³ã«
`__iter__`ãš`__next__`ãçè§£ããããšã§ãPythonã®ãããããšããã§ãããã®åœ±é¿ãèŠãããšãã§ããŸããããã¯Pythonã®éåžžã«å€ãã®æ©èœãã·ãŒã ã¬ã¹ã«é£æºããããšãå¯èœã«ããçµ±äžãããã³ã«ã§ãã
`for`ã«ãŒãã*å®éã«*ã©ã®ããã«æ©èœããã
ãããŸã§æé»çã«è°è«ããŠããŸããããæç€ºçã«ããŸããããPythonããã®è¡ã«ééãããšã:
`for item in my_iterable:`
èå°è£ã§ä»¥äžã®æé ãå®è¡ããŸã:
- `iter(my_iterable)`ãåŒã³åºããŠã€ãã¬ãŒã¿ãååŸããŸããããã¯ã`my_iterable.__iter__()`ãåŒã³åºããŸããè¿ããããªããžã§ã¯ãã`iterator_obj`ãšåŒã³ãŸãããã
- ç¡é`while True`ã«ãŒãã«å ¥ããŸãã
- ã«ãŒãå ã§ã`next(iterator_obj)`ãåŒã³åºããŸããããã¯ã`iterator_obj.__next__()`ãåŒã³åºããŸãã
- ãã`__next__`ãå€ãè¿ããå Žåãããã¯`item`倿°ã«ä»£å ¥ããã`for`ã«ãŒããããã¯å ã®ã³ãŒããå®è¡ãããŸãã
- ãã`__next__`ã`StopIteration`äŸå€ãçºçãããå Žåã`for`ã«ãŒãã¯ãã®äŸå€ããã£ããããå éšã®`while`ã«ãŒããæãåºããŸããããã§ã€ãã¬ãŒã·ã§ã³ã¯å®äºã§ãã
å å 衚èšãšãžã§ãã¬ãŒã¿åŒ
ãªã¹ããã»ãããèŸæžã®å å 衚èšã¯ãã¹ãŠã€ãã¬ãŒã¿ãããã³ã«ã«ãã£ãŠé§åãããŠããŸããæ¬¡ã®ããã«æžããš:
`squares = [x * x for x in range(10)]`
Pythonã¯å®è³ªçã«`range(10)`ãªããžã§ã¯ãã«å¯ŸããŠã€ãã¬ãŒã·ã§ã³ãå®è¡ããåå€ãååŸãã`x * x`ã®åŒãå®è¡ããŠãªã¹ããæ§ç¯ããŠããŸããããã¯ãé å»¶ã€ãã¬ãŒã·ã§ã³ãããã«çŽæ¥çã«äœ¿çšãããžã§ãã¬ãŒã¿åŒã«ã€ããŠãåæ§ã§ã:
`lazy_squares = (x * x for x in range(1000000))`
ããã¯ã¡ã¢ãªäžã«100äžåã®ã¢ã€ãã ãæã€ãªã¹ããäœæããããã§ã¯ãããŸãããããã¯ãã€ãã¬ãŒãããéã«å¹³æ¹æ°ã1ã€ãã€èšç®ããã€ãã¬ãŒã¿ (å ·äœçã«ã¯ãžã§ãã¬ãŒã¿ãªããžã§ã¯ã) ãäœæããŸãã
ãžã§ãã¬ãŒã¿: ã€ãã¬ãŒã¿ãäœæããããã·ã³ãã«ãªæ¹æ³
`__iter__`ãš`__next__`ãæã€å®å šãªã¯ã©ã¹ãäœæããããšã¯æå€§ã®å¶åŸ¡ãæäŸããŸãããåçŽãªã±ãŒã¹ã§ã¯åé·ã«ãªãããšããããŸããPythonã¯ã€ãã¬ãŒã¿ãäœæããããã®ããç°¡æœãªæ§æãããªãã¡ãžã§ãã¬ãŒã¿ãæäŸããŠããŸãã
ãžã§ãã¬ãŒã¿ã¯ã`yield`ããŒã¯ãŒãã䜿çšãã颿°ã§ãããžã§ãã¬ãŒã¿é¢æ°ãåŒã³åºããšãã³ãŒãã¯å®è¡ãããŸããã代ããã«ãå®å šãªã€ãã¬ãŒã¿ã§ãããžã§ãã¬ãŒã¿ãªããžã§ã¯ããè¿ããŸãã
`CountUpTo`ã®äŸããžã§ãã¬ãŒã¿ãšããŠæžãçŽããŠã¿ãŸããã:
ã³ãŒã:
def count_up_to_generator(max_num):
"""A generator function that yields numbers from 1 to max_num."""
print("Generator started...")
current = 1
while current <= max_num:
yield current # Pauses here and sends a value back
current += 1
print("Generator finished.")
# How to use it
counter_gen = count_up_to_generator(3)
for number in counter_gen:
print(f"For loop received: {number}")
ã©ãã»ã©ã·ã³ãã«ã«ãªã£ããèŠãŠãã ããïŒããã§éæ³ãèµ·ãããŠããã®ã¯`yield`ããŒã¯ãŒãã§ãã`yield`ã«ééãããšã颿°ã®ç¶æ ã¯åçµãããå€ã¯åŒã³åºãå ã«éããã颿°ã¯äžæåæ¢ããŸããæ¬¡ã«ãžã§ãã¬ãŒã¿ãªããžã§ã¯ãã«å¯ŸããŠ`__next__`ãåŒã³åºããããšã颿°ã¯äžæããå Žæããå®è¡ãåéããå¥ã®`yield`ã«å°éããã颿°ãçµäºãããŸã§ç¶è¡ããŸãã颿°ãçµäºãããšã`StopIteration`ãèªåçã«çºçããŸãã
å éšã§ã¯ãPythonã¯èªåçã«`__iter__`ã¡ãœãããš`__next__`ã¡ãœãããæã€ãªããžã§ã¯ããäœæããŠããŸãããžã§ãã¬ãŒã¿ã®æ¹ãå®çšçãªéžæè¢ãšãªãããšãå€ãã§ãããåºç€ãšãªããããã³ã«ãçè§£ããããšã¯ããããã°ãè€éãªã·ã¹ãã ã®èšèšããããŠPythonã®ã³ã¢ã¡ã«ãã¯ã¹ãã©ã®ããã«æ©èœããããçè§£ããããã«äžå¯æ¬ ã§ãã
ãã¹ããã©ã¯ãã£ã¹ãšããããèœãšã穎
ã€ãã¬ãŒã¿ãããã³ã«ãå®è£ ããéã¯ãäžè¬çãªãšã©ãŒãé¿ããããã«ä»¥äžã®ã¬ã€ãã©ã€ã³ã念é ã«çœ®ããŠãã ããã
ãã¹ããã©ã¯ãã£ã¹
- ã€ãã©ãã«ãšã€ãã¬ãŒã¿ãåé¢ãã: è€æ°åèµ°æ»ããµããŒãããå¿ èŠãããã³ã³ãããªããžã§ã¯ãã«ã€ããŠã¯ãå¿ ãã€ãã¬ãŒã¿ãå¥ã®ã¯ã©ã¹ã§å®è£ ããŠãã ãããã³ã³ããã®`__iter__`ã¡ãœããã¯ãæ¯åã€ãã¬ãŒã¿ã¯ã©ã¹ã®æ°ããã€ã³ã¹ã¿ã³ã¹ãè¿ãå¿ èŠããããŸãã
- åžžã«`StopIteration`ãçºçããã: `__next__`ã¡ãœããã¯ãçµäºãéç¥ããããã«ç¢ºå®ã«`StopIteration`ãçºçãããªããã°ãªããŸããããããå¿ãããšç¡éã«ãŒãã«ã€ãªãããŸãã
- ã€ãã¬ãŒã¿ã¯ã€ãã©ãã«ã§ããã¹ã: ã€ãã¬ãŒã¿ã®`__iter__`ã¡ãœããã¯åžžã«`self`ãè¿ãã¹ãã§ããããã«ãããã€ãã©ãã«ãæåŸ ãããããããå Žæã§ã€ãã¬ãŒã¿ã䜿çšã§ããŸãã
- ã·ã³ãã«ãã®ããã«ãžã§ãã¬ãŒã¿ãåªå ãã: ã€ãã¬ãŒã¿ã®ããžãã¯ãåçŽã§ãåäžã®é¢æ°ãšããŠè¡šçŸã§ããå Žåã¯ããžã§ãã¬ãŒã¿ãã»ãšãã©åžžã«ã¯ãªãŒã³ã§èªã¿ãããã§ããããè€éãªç¶æ ãã¡ãœãããã€ãã¬ãŒã¿ãªããžã§ã¯ãèªäœã«é¢é£ä»ããå¿ èŠãããå Žåã¯ãå®å šãªã€ãã¬ãŒã¿ã¯ã©ã¹ã䜿çšããŠãã ããã
ããããèœãšã穎
- 䜿ãåãã€ãã¬ãŒã¿ã®åé¡: è°è«ããããã«ããªããžã§ã¯ããããèªèº«ã®ã€ãã¬ãŒã¿ã§ããå ŽåãäžåºŠãã䜿çšã§ããªãããšã«æ³šæããŠãã ãããè€æ°åã€ãã¬ãŒãããå¿ èŠãããå Žåã¯ãæ°ããã€ã³ã¹ã¿ã³ã¹ãäœæããããã€ãã©ãã«/ã€ãã¬ãŒã¿åé¢ãã¿ãŒã³ã䜿çšããå¿ èŠããããŸãã
- ç¶æ ã®å¿ã: `__next__`ã¡ãœããã¯ã€ãã¬ãŒã¿ã®å éšç¶æ (äŸ: ã€ã³ããã¯ã¹ã®ã€ã³ã¯ãªã¡ã³ãããã€ã³ã¿ã®é²è¡) ã倿Žããå¿ èŠããããŸããç¶æ ãæŽæ°ãããªããšã`__next__`ã¯åãå€ãç¹°ãè¿ãè¿ããç¡éã«ãŒããåŒãèµ·ããå¯èœæ§ããããŸãã
- ã€ãã¬ãŒãäžã®ã³ã¬ã¯ã·ã§ã³ã®å€æŽ: ã³ã¬ã¯ã·ã§ã³ãã€ãã¬ãŒãäžã«å€æŽãã (`for`ã«ãŒãå ã§ãªã¹ãããã¢ã€ãã ãåé€ãããªã©) ãšãã¢ã€ãã ã®ã¹ããããäºæãã¬ãšã©ãŒã®çºçãªã©ãäºæž¬äžå¯èœãªåäœã«ã€ãªããå¯èœæ§ããããŸããå ã®ã³ã¬ã¯ã·ã§ã³ã倿Žããå¿ èŠãããå Žåã¯ãã³ã¬ã¯ã·ã§ã³ã®ã³ããŒãã€ãã¬ãŒãããæ¹ãäžè¬çã«å®å šã§ãã
çµè«
ã€ãã¬ãŒã¿ãããã³ã«ã¯ãã·ã³ãã«ãª`__iter__`ã¡ãœãããš`__next__`ã¡ãœããã«ãããPythonã«ãããã€ãã¬ãŒã·ã§ã³ã®åºç€ããªããŠããŸããããã¯ã匷åã§è€éãªæ¯ãèããå¯èœã«ããã·ã³ãã«ã§äžè²«æ§ã®ããã€ã³ã¿ãŒãã§ãŒã¹ãåªå ãããšãããèšèªã®èšèšå²åŠã®èšŒã§ããé æ¬¡ããŒã¿ã¢ã¯ã»ã¹ã«å¯Ÿããæ®éçãªå¥çŽãæäŸããããšã§ããã®ãããã³ã«ã¯`for`ã«ãŒããå å 衚èšããã®ä»æ°ãåããªãã»ã©ã®ããŒã«ãããã®èšèªã話ãããšãéžæãããããããªããžã§ã¯ããšã·ãŒã ã¬ã¹ã«é£æºããããšãå¯èœã«ããŸãã
ãã®ãããã³ã«ãç¿åŸããããšã§ãPythonãšã³ã·ã¹ãã ã«ãããŠäžæµã®ååšãšãªãç¬èªã®ã·ãŒã±ã³ã¹ã©ã€ã¯ãªãªããžã§ã¯ããäœæããèœåãè§£æŸããŸãããããã§ãããŒã¿ãé å»¶åŠçããããšã§ããã¡ã¢ãªå¹çãé«ããæšæºçãªPythonæ§æãšã¯ãªãŒã³ã«çµ±åããããšã§ããçŽæçã§ããããŠæçµçã«ã¯ãã匷åãªã¯ã©ã¹ãæžãããšãã§ããŸããæ¬¡ã«`for`ã«ãŒããæžããšãã¯ã衚é¢äžã§èµ·ãã£ãŠãã`__iter__`ãš`__next__`ã®åªé ãªãã³ã¹ã«å°ãã®éæè¬ããŠã¿ãŠãã ããã